<script setup>
import { ref } from 'vue';
import useFileCutter from './useFileCutter';
import dayjs from 'dayjs';
import { filesize } from 'filesize';
import { CustomTimer } from '../../../utils/customTimer';
import { CHUNK_SIZE, createFileChunk } from '../../../utils/createFileChunk';

const { cutFile } = useFileCutter();

// 文件列表
const fileList = ref([]);

// 设置文件
const setFileList = e => {
    fileList.value = [...e.target.files];
};

// 文件进入
const fileEnter = e => e.preventDefault();

// 文件悬浮
const fileOver = e => e.preventDefault();

// 添加文件
const addFile = async e => {
    e.preventDefault();
    const result = await resolveFileDirectory(e.dataTransfer.items);
    fileList.value = result;
};

// 清空文件
const clearFile = () => fileList.value = [];

// 递归处理文件、文件夹
const resolveFileDirectory = async (items, result = []) => {
    // 传输项转化文件
    const entries = items instanceof DataTransferItemList ? [...items].map(item => item.webkitGetAsEntry()) : items;
    for (const entry of entries) {
        // 判断文件、文件夹
        if (entry.isFile) {
            const file = await new Promise((resolve, reject) => entry.file(file => resolve(file), err => reject(err)));
            result.push(file);
        } else if (entry.isDirectory) {
            const entries = await new Promise((resolve, reject) => entry.createReader().readEntries(entries => resolve(entries), err => reject(err)));
            await resolveFileDirectory(entries, result);
        }
    }
    return result;
};

// 读取文件
const readFile = async function () {
    if (fileList.value.length > 0) {
        const timer = new CustomTimer();
        timer.start();
        const results = [];
        for (let i = 0; i < fileList.value.length; i++) {
            const file = fileList.value[i];
            // 切割处理
            if (file.size > CHUNK_SIZE) {
                const result = await cutFile(file);
                results.push(result);
            } else {
                const result = await createFileChunk(file);
                results.push(result);
            }
        }
        ElMessage({ type: 'success', message: `用时：${timer.stop()} ms` });
        console.log(results);
    }
};

// 大小格式化
const sizeFormatter = (_row, _column, size) => {
    return filesize(size);
};

// 日期格式化
const dateFormatter = (_row, _column, date) => {
    return dayjs(date).format('YYYY-MM-DD HH:mm:ss');
};
</script>

<template>
    <el-card :style="{ width: '100%' }">
        <div class="container" @dragenter="fileEnter" @dragover="fileOver" @drop="addFile">
            <div class="content">
                <el-icon :size="48">
                    <UploadFilled />
                </el-icon>
                <el-text>请将文件拖拽至此区域上传</el-text>
            </div>
        </div>
        <div class="row">
            <el-button type="primary" class="upload-btn">选择文件
                <input type="file" @change="setFileList" multiple />
            </el-button>
            <el-button type="primary" class="upload-btn">选择文件夹
                <input type="file" @change="setFileList" webkitdirectory mozdirectory odirectory />
            </el-button>
            <el-button type="primary" class="upload-btn" @click="clearFile">清空</el-button>
            <el-button type="primary" class="upload-btn" @click="readFile">上传</el-button>
        </div>
        <el-table :data="fileList" style="width: 100%">
            <el-table-column prop="name" label="Name" />
            <el-table-column prop="size" label="Size" :formatter="sizeFormatter" />
            <el-table-column prop="lastModifiedDate" label="Last Modified Date" :formatter="dateFormatter" />
        </el-table>
    </el-card>
</template>

<style scoped lang="scss">
.container {
    position: relative;
    margin: 0 auto;
    width: 100%;
    height: 8rem;
    border: 0.125rem dashed grey;
    border-radius: 0.5rem;

    .content {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        display: flex;
        flex-direction: column;
        align-items: center;
    }
}

.row {
    margin: 1rem 0;
    width: 100%;

    .upload-btn {
        position: relative;

        input[type='file'] {
            position: absolute;
            width: 100%;
            height: 100%;
            left: 0;
            top: 0;
            opacity: 0;
        }
    }
}
</style>